package com.common.jane_ai.config;

import com.common.jane_ai.advisor.RedisChatHistoryAdvisor;
import com.common.jane_ai.advisor.RedisChatHistoryTitleAdvisor;
import com.common.jane_ai.functioncalling.JaneMarkController;
import com.common.jane_ai.rag.MarkdownLoader;
import com.common.jane_ai.redis_chat_memory.RedisChatMemoryRepository;
import com.common.jane_ai.redis_chat_memory.dialect.RedisChatMemoryRepositoryDialect;
import com.common.jane_ai.service.RedisChatHistoryAdvisorService;
import org.aspectj.apache.bcel.classfile.Module;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.ai.document.Document;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiEmbeddingModel;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.vectorstore.pinecone.PineconeVectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.util.List;

import static com.common.jane_ai.constant.JaneDescConstant.*;

//@Configuration + @Bean 是标准且推荐的方式向 Spring IOC 容器中注入对象。
//不需要配置 META-INF 下的 spring.factories / spring.components，除非你在开发“自动装配的库”
@Configuration
public class JaneAIConfiguration{

    @Autowired
    private RedisChatHistoryAdvisorService redisChatHistoryAdvisorService;

    @Bean                               //参数在容器中自动获取，无需显式注入
    public ChatMemoryRepository chatMemoryRepository(RedisChatMemoryRepositoryDialect dialect) {
        return new RedisChatMemoryRepository(dialect);
    }

    @Bean
    public MarkdownLoader markdownLoader(ResourcePatternResolver resourcePatternResolver) {
        return new MarkdownLoader(resourcePatternResolver);
    }

    @Bean
    public ChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository) {
        return MessageWindowChatMemory.builder()
                .chatMemoryRepository(chatMemoryRepository)
                .maxMessages(30)
                .build();

    }



//    @Bean(name = "openAiEmbeddingModel")
//    public VectorStore vectorStore(@Qualifier("openAiEmbeddingModel")OpenAiEmbeddingModel embeddingModel) {
//        return PineconeVectorStore.builder(embeddingModel)
//                .apiKey(pineconeApiKey)
//                .indexName(pineconeIndexName)
//                .build();
//    }
    @Bean(name = "titleChatClient")// 生成Title
    public ChatClient titleChatClient(OpenAiChatModel model) {
//    public ChatClient titleChatClient(DeepSeekChatModel model) {
        return ChatClient
                .builder(model)
                .defaultAdvisors(
                        new SimpleLoggerAdvisor()
                )
                .build();
    }

    @Bean(name = "chatClient")
//    public ChatClient chatClient(DeepSeekChatModel chatModel) {
    //ChatClient 是基于 Reactor 的异步响应式执行模型
    public ChatClient chatClient(OpenAiChatModel chatModel, ChatMemory chatMemory, @Qualifier("titleChatClient") ChatClient chatClient) {
//    public ChatClient chatClient(DeepSeekChatModel chatModel, ChatMemory chatMemory, @Qualifier("titleChatClient") ChatClient chatClient) {
        return ChatClient.builder(chatModel)
                .defaultSystem(JANE_DESC)//系统描述
                .defaultAdvisors(
                        // chat请求的拦截器增强器
                        new SimpleLoggerAdvisor(),//DEBUG日志记录器
                        RedisChatHistoryAdvisor.builder(redisChatHistoryAdvisorService)
                                .order(JANE_CHAT_HISTORY_ADVISOR_ORDER).build(),
                        RedisChatHistoryTitleAdvisor.builder(redisChatHistoryAdvisorService)
                                .order(JANE_CHAT_TITLE_ADVISOR_ORDER)
                                .chatMemory(chatMemory).chatClient(chatClient)
                                .build(),
                        MessageChatMemoryAdvisor.builder(chatMemory).order(JANE_CHAT_MEMORY_ADVISOR_ORDER).build()
                )
                .build();
    }

    @Bean(name = "RAG_Pinecone_chatClient")
//   RAG Client
    public ChatClient RAGchatClient(OpenAiChatModel chatModel, ChatMemory chatMemory, @Qualifier("titleChatClient") ChatClient chatClient,
//    public ChatClient RAGchatClient(DeepSeekChatModel chatModel, ChatMemory chatMemory, @Qualifier("titleChatClient") ChatClient chatClient,
                                    MarkdownLoader markdownLoader, VectorStore vectorStore,
                                    JaneMarkController janeMarkController) {
//        List<Document> documents = markdownLoader.loadMarkdowns();
//        int batchSize = 10;
//        for (int i = 0; i < documents.size(); i += batchSize) {
//            int end = Math.min(i + batchSize, documents.size());
//            List<Document> batch = documents.subList(i, end);
//            vectorStore.add(batch); // 每次添加不超过 10 条
//        }
        //限制	embedding 一次最多传 10 条，太多会报 400

        return ChatClient.builder(chatModel)
                .defaultSystem(JANE_DESC)//系统描述
                .defaultAdvisors(
                        // chat请求的拦截器增强器
                        new SimpleLoggerAdvisor(),//DEBUG日志记录器
                        RedisChatHistoryAdvisor.builder(redisChatHistoryAdvisorService)
                                .order(JANE_CHAT_HISTORY_ADVISOR_ORDER).build(),
                        RedisChatHistoryTitleAdvisor.builder(redisChatHistoryAdvisorService)
                                .order(JANE_CHAT_TITLE_ADVISOR_ORDER)
                                .chatMemory(chatMemory).chatClient(chatClient)
                                .build(),
                        MessageChatMemoryAdvisor.builder(chatMemory)
                                .order(JANE_CHAT_MEMORY_ADVISOR_ORDER).build(),
                        QuestionAnswerAdvisor.builder(vectorStore)
                                .searchRequest(SearchRequest.builder()
                                        .similarityThreshold(0.7)//相似度赋值
                                        .topK(8)// 返回的相似文档数量
                                        .build())
                                .build()
                        //ChatClient 会自动从向量数据库中检索相关文档，并将这些文档作为上下文拼接进用户提问的 Prompt 中（也就是放进 Q）去参与问答生成
                )
                .defaultTools(janeMarkController)
                .build();
        // 相似度阈值
        //作用：设置余弦相似度的下限值。
        //含义：只有相似度 ≥ 0.7 的文档才会被返回。
        //默认值：通常是 0.0（即不限制），你设置为 0.7 说明你只要“更相关”的文档。
        //范围：0.0 ~ 1.0，1.0 表示完全一致。
    }
}
